﻿using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Budget.Silver.Core.Messages;
using Budget.Silver.StatisticsServiceReference;
using Castle.Core;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace Budget.Silver.ViewModel
{
    [Transient]
    public class StatisticsViewModel : ViewModelBase
    {
        private readonly StatisticsServiceClient service;

        private ObservableCollection<StatisticByCategoryData> categoryOutcomes;
        private ObservableCollection<StatisticByYearData> yearOutcomes;
        private ObservableCollection<StatisticByMonthData> monthOutcomes; 
        private DateTime from, to, monthFrom, monthTo;

        #region Completed methods

        private void AddCompletedEvents()
        {
            service.GetStatisticsByCategoriesCompleted += ServiceOnGetStatisticsByCategoriesCompleted;
            service.GetStatisticsByMonthesCompleted += ServiceOnGetStatisticsByMonthesCompleted;
            service.GetStatisticsByYearCompleted += ServiceOnGetStatisticsByYearCompleted;
        }

        private void ServiceOnGetStatisticsByYearCompleted(object sender, GetStatisticsByYearCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                YearOutcomes = e.Result;
            }
            else
            {
                MessengerInstance.Send(new ExceptionMessage(e.Error));
            }

            MessengerInstance.Send(new BusyMessage(false));
        }

        private void ServiceOnGetStatisticsByMonthesCompleted(object sender, GetStatisticsByMonthesCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                MonthOutcomes = e.Result;
            }
            else
            {
                MessengerInstance.Send(new ExceptionMessage(e.Error));
            }

            MessengerInstance.Send(new BusyMessage(false));
        }

        private void ServiceOnGetStatisticsByCategoriesCompleted(object sender, GetStatisticsByCategoriesCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                CategoryOutcomes = e.Result;
            }
            else
            {
                MessengerInstance.Send(new ExceptionMessage(e.Error));
            }

            MessengerInstance.Send(new BusyMessage(false));
        }

        #endregion

        #region Commands

        private void CreateCommands()
        {
            SearchByCategories = new RelayCommand(SearchByCategoriesCommand);
            SearchByMonthes = new RelayCommand(SearchByMonthesCommand);
        }

        private void SearchByMonthesCommand()
        {
            MessengerInstance.Send(new BusyMessage(true));
            service.GetStatisticsByMonthesAsync(MonthFromDate, MonthToDate);
        }

        private void SearchByCategoriesCommand()
        {
            MessengerInstance.Send(new BusyMessage(true));
            service.GetStatisticsByCategoriesAsync(FromDate, ToDate);
        }

        #endregion

        public ObservableCollection<StatisticByCategoryData> CategoryOutcomes
        {
            get { return categoryOutcomes; }
            set
            {
                if (!Equals(categoryOutcomes, value))
                {
                    categoryOutcomes = value;

                    RaisePropertyChanged(() => CategoryOutcomes);
                }
            }
        }

        public ObservableCollection<StatisticByYearData> YearOutcomes
        {
            get { return yearOutcomes; }
            set
            {
                if (!Equals(yearOutcomes, value))
                {
                    yearOutcomes = value;

                    RaisePropertyChanged(() => YearOutcomes);
                }
            }
        }

        public ObservableCollection<StatisticByMonthData> MonthOutcomes
        {
            get { return monthOutcomes; }
            set
            {
                if (!Equals(monthOutcomes, value))
                {
                    monthOutcomes = value;

                    RaisePropertyChanged(() => MonthOutcomes);
                }
            }
        }

        public DateTime FromDate
        {
            get { return from; }
            set
            {
                if (from != value)
                {
                    from = value;
                    RaisePropertyChanged(() => FromDate);
                }
            }
        }

        public DateTime ToDate
        {
            get { return to; }
            set
            {
                if (to != value)
                {
                    to = value;
                    RaisePropertyChanged(() => ToDate);
                }
            }
        }

        public DateTime MonthFromDate
        {
            get { return monthFrom; }
            set
            {
                if (monthFrom != value)
                {
                    monthFrom = value;
                    RaisePropertyChanged(() => MonthFromDate);
                }
            }
        }

        public DateTime MonthToDate
        {
            get { return monthTo; }
            set
            {
                if (monthTo != value)
                {
                    monthTo = value;
                    RaisePropertyChanged(() => MonthToDate);
                }
            }
        }

        public ICommand SearchByCategories { get; private set; }

        public ICommand SearchByMonthes { get; private set; }

        public StatisticsViewModel(StatisticsServiceClient service)
        {
            this.service = service;
            CreateCommands();
            AddCompletedEvents();
            FromDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            ToDate = DateTime.Now;
            MonthFromDate = new DateTime(DateTime.Now.Year, 1, 1);
            MonthToDate = DateTime.Now;
            MessengerInstance.Send(new BusyMessage(true));
            service.GetStatisticsByCategoriesAsync(FromDate, ToDate);
            service.GetStatisticsByMonthesAsync(MonthFromDate, MonthToDate);
            service.GetStatisticsByYearAsync();
        }
    }
}